package com.fedming.bottomnavigationdemo.Call;

import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fedming.bottomnavigationdemo.HomeActivity;
import com.fedming.bottomnavigationdemo.R;
import com.fedming.bottomnavigationdemo.Util.HttpUtils;

import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.RtpReceiver;
import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoEncoderFactory;
import org.webrtc.VideoTrack;

import java.io.IOException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class AudioCallActivity extends AppCompatActivity {
    //设置分辨率和帧数
    private static final int VIDEO_RESOLUTION_WIDTH = 640;
    private static final int VIDEO_RESOLUTION_HEIGHT = 480;
    private static final int VIDEO_FPS = 24;

    private String mState = "init"; //记录当前client状态


    private static final String TAG = "AudioCall";

    public static final String VIDEO_TRACK_ID = "1";//"ARDAMSv0";
    public static final String AUDIO_TRACK_ID = "2";//"ARDAMSa0";

    //用于数据传输
    private PeerConnection mPeerConnection;
    private PeerConnectionFactory mPeerConnectionFactory;

    //OpenGL ES
    private EglBase mRootEglBase;
    //纹理渲染
    private SurfaceTextureHelper mSurfaceTextureHelper;

    //UI 继承自 surface view
    //private SurfaceViewRenderer mLocalSurfaceView;
    //private SurfaceViewRenderer mRemoteSurfaceView;

    private VideoTrack mVideoTrack;
    private AudioTrack mAudioTrack;
    CallHandler handler;
    public static final int WHAT_DELAY_END_CALL = 0x01;
    private TextView stateText; //正在等待对方接听这个文字



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //getSupportActionBar().hide();
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        hideBottomUIMenu();
        setContentView(R.layout.audio_call2);

        mRootEglBase = EglBase.create();

        handler = new CallHandler();//消息处理
        stateText = (TextView) findViewById(R.id.TextView);
        //创建 factory， pc（peer connection）是从factory里获得的
        mPeerConnectionFactory = createPeerConnectionFactory(this);
        //音频捕获
        changeToSpeaker(getApplicationContext());
        //setWiredHead(getApplicationContext());
        AudioSource audioSource = mPeerConnectionFactory.createAudioSource(createAudioConstraints());
        mAudioTrack = mPeerConnectionFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource);
        mAudioTrack.setEnabled(true);

        my_SignalClient.getInstance().setSignalEventListener(mOnSignalEventListener);

        mPeerConnection = createPeerConnection();



        if (my_SignalClient.getInstance().initiator){
            //播放打电话接通前的声音
            my_SignalClient.getInstance().callingOutMusicPlay();
            HomeActivity.physicalLight("闪灯");
            //标志此时正在等待对方接听
            my_SignalClient.getInstance().Waiting = true;
            //1分钟之后未接通，则挂断电话
            handler.sendEmptyMessageDelayed(WHAT_DELAY_END_CALL, 60 * 1000);
            //主动拨打,向服务器发送connect
            Log.e(TAG,"向远端发送connect请求");
            JSONObject tosend = new JSONObject();
            tosend.put("type","connect");
            JSONObject inner_message = new JSONObject();
            inner_message.put("userId",my_SignalClient.getInstance().userId);
            inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);

            //默认音频通信
            inner_message.put("video",my_SignalClient.getInstance().isVideoCall);

            tosend.put("message",inner_message);
            my_SignalClient.getInstance().sendMessage(tosend);

        }
        else {
            //被拨打触发，向服务器发送start消息
            Log.e(TAG,"向远端发送start");
            JSONObject tosend = new JSONObject();
            tosend.put("type","start");
            JSONObject inner_message = new JSONObject();
            inner_message.put("userId",my_SignalClient.getInstance().userId);
            inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);
            tosend.put("message",inner_message); //json对象的一个value也是json对象
            my_SignalClient.getInstance().sendMessage(tosend);
        }
        //设置挂断按钮监听
        findViewById(R.id.hangupBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                new Thread(new Runnable() {

                    String body = null;
                    @Override
                    public void run() {
                        try {
                            String url_server = "http://"+HomeActivity.server_ip+":"+HomeActivity.info_port+"";//添加路径
                            String url = url_server+HomeActivity.path+"?ask=false"+"&id="+HomeActivity.bedID+"&type=call";
                            System.out.println(url);
                            body= HttpUtils.get(url).body().string();
                            System.out.println("返回的body:"+body);
                            Thread.sleep(2000);
                        } catch (Exception e) {
                            //e.printStackTrace();
                            System.out.println("no response");
                        }
                    }
                }).start();
                HomeActivity.t3 = ""+ new Date().getTime()/1000*1000;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String body = null;
                        System.out.println("t1,t2,t3:"+HomeActivity.t1+"??"+HomeActivity.t2+"??"+HomeActivity.t3);
                        JSONObject json=new JSONObject();
                        if (HomeActivity.t2==""){
                            json.put("startTime",HomeActivity.t1);
                            json.put("status","未接听");
                        }
                        else{
                            json.put("startTime",HomeActivity.t2);
                            json.put("status","已接听");
                        }
                        json.put("endTime",HomeActivity.t3);
                        if (HomeActivity.t1==""){
                            json.put("callId",Integer.parseInt(HomeActivity.stationDeviceID));
                            json.put("callName","station");
                            json.put("calledId",Integer.parseInt(HomeActivity.localdeviceID));
                            json.put("calledName",HomeActivity.name);
                        }
                        else{
                            json.put("callId",Integer.parseInt(HomeActivity.localdeviceID));
                            json.put("callName",HomeActivity.name);
                            json.put("calledId",Integer.parseInt(HomeActivity.stationDeviceID));
                            json.put("calledName","station");
                        }
                        try {
                            body = HttpUtils.post("http://"+HomeActivity.server_ip+":"+HomeActivity.info_port+HomeActivity.path4,json.toString()).body().string();
                        } catch (IOException e) {
                            //e.printStackTrace();
                            System.out.println("no response");
                        }
                        System.out.println(body);
                    }
                }).start();
                my_SignalClient.getInstance().Waiting = false; //这一句是为了在未接通情况下己方挂断，同样设置等待为false，避免WHAT_DELAY_END_CALL事件被调用
                my_SignalClient.getInstance().callingOutMusicStop(); //停止音乐
                if(HomeActivity.t2=="")
                    doCancel();
                else
                    doBye();
                finish();//finish()会调用onDestroy()函数并销毁活动
            }
        });
        //changeToSpeaker(getApplicationContext());
    }
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_F9://开始呼叫
            case KeyEvent.KEYCODE_F12://开始换药
                findViewById(R.id.hangupBtn).performClick();
                return true;
        }
        return super.onKeyUp(keyCode,event);
    }
    public void doCancel(){
        JSONObject tosend = new JSONObject();
        tosend.put("type","cancel");
        JSONObject inner_message = new JSONObject();
        inner_message.put("userId",my_SignalClient.getInstance().userId);
        inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);
        tosend.put("message",inner_message); //json对象的一个value也是json对象
        my_SignalClient.getInstance().sendMessage(tosend);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),"通话结束",Toast.LENGTH_LONG).show();
                my_SignalClient.getInstance().callEndRing();
            }
        });
    }
    public void doBye(){
        JSONObject tosend = new JSONObject();
        tosend.put("type","hangup");
        JSONObject inner_message = new JSONObject();
        inner_message.put("userId",my_SignalClient.getInstance().userId);
        inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);
        tosend.put("message",inner_message); //json对象的一个value也是json对象
        my_SignalClient.getInstance().sendMessage(tosend);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),"通话结束",Toast.LENGTH_LONG).show();
                my_SignalClient.getInstance().callEndRing();
            }
        });
    }
    protected void hideBottomUIMenu() {
        //隐藏虚拟按键，并且全屏
        if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
            View v = this.getWindow().getDecorView();
            v.setSystemUiVisibility(View.GONE);
        } else if (Build.VERSION.SDK_INT >= 19) {

            Window _window = getWindow();
            WindowManager.LayoutParams params = _window.getAttributes();
            params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE;
            _window.setAttributes(params);
        }
    }

    public static void setWiredHead(Context context) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        audioManager.startBluetoothSco();
        audioManager.setBluetoothScoOn(true);
        audioManager.setSpeakerphoneOn(false);
    }
    public static void changeToSpeaker(Context context) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.STREAM_VOICE_CALL);
        System.out.println("当前音量前:"+audioManager.getStreamVolume(audioManager.getMode()));
        audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,audioManager.getStreamMaxVolume(audioManager.getMode()),0);
        System.out.println("最大音量:"+audioManager.getStreamMaxVolume(audioManager.getMode()));
        System.out.println("当前音量:"+audioManager.getStreamVolume(audioManager.getMode()));

        audioManager.stopBluetoothSco();
        audioManager.setBluetoothScoOn(false);
        audioManager.setSpeakerphoneOn(true);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        doLeave();
        my_SignalClient.getInstance().callingOutMusicStop(); //停止音乐
        handler.removeMessages(WHAT_DELAY_END_CALL);//记得撤销这个消息，活动结束后handler队列里的消息不会自动撤销的，以防下次活动激活后旧的消息仍留在队列里面
        PeerConnectionFactory.stopInternalTracingCapture();
        PeerConnectionFactory.shutdownInternalTracer();
        mPeerConnectionFactory.dispose();

    }
    class CallHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == WHAT_DELAY_END_CALL) {
                HomeActivity.t3 = ""+new Date().getTime()/1000*1000;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String body = null;
                        System.out.println("t1,t2,t3:"+HomeActivity.t1+"??"+HomeActivity.t2+"??"+HomeActivity.t3);
                        JSONObject json=new JSONObject();
                        if (HomeActivity.t2==""){
                            json.put("startTime",HomeActivity.t1);
                            json.put("status","未接听");
                        }
                        else{
                            json.put("startTime",HomeActivity.t2);
                            json.put("status","已接听");
                        }
                        json.put("endTime",HomeActivity.t3);
                        if (HomeActivity.t1==""){
                            json.put("callId",Integer.parseInt(HomeActivity.stationDeviceID));
                            json.put("callName","station");
                            json.put("calledId",Integer.parseInt(HomeActivity.localdeviceID));
                            json.put("calledName",HomeActivity.name);
                        }
                        else{
                            json.put("callId",Integer.parseInt(HomeActivity.localdeviceID));
                            json.put("callName",HomeActivity.name);
                            json.put("calledId",Integer.parseInt(HomeActivity.stationDeviceID));
                            json.put("calledName","station");
                        }

                        try {
                            body = HttpUtils.post("http://"+HomeActivity.server_ip+":"+HomeActivity.info_port+HomeActivity.path4,json.toString()).body().string();
                        } catch (IOException e) {
                            //e.printStackTrace();
                            System.out.println("no response");
                        }
                        System.out.println(body);
                    }
                }).start();
                if (my_SignalClient.getInstance().Waiting) { //过了60秒之后，如果还是在等待状态，就结束这活动
                    new Thread(new Runnable() {

                        String body = null;
                        @Override
                        public void run() {
                            try {
                                String url_server = "http://"+HomeActivity.server_ip+":"+HomeActivity.info_port+"";//添加路径
                                String url = url_server+HomeActivity.path+"?ask=false"+"&id="+HomeActivity.bedID+"&type=call";
                                System.out.println(url);
                                body= HttpUtils.get(url).body().string();
                                System.out.println("返回的body:"+body);
                                Thread.sleep(2000);
                            } catch (Exception e) {
                                //e.printStackTrace();
                                System.out.println("no response");
                            }
                        }
                    }).start();
                    my_SignalClient.getInstance().callingOutMusicStop();
                    my_SignalClient.getInstance().callEndRing();
                    doBye();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"护士站暂时无人接听",Toast.LENGTH_LONG).show();
                        }
                    });

                    finish();
                }
            }
        }

    }

    public static class SimpleSdpObserver implements SdpObserver {
        @Override
        public void onCreateSuccess(SessionDescription sessionDescription) {
            Log.i(TAG, "SdpObserver: onCreateSuccess成功");
        }

        @Override
        public void onSetSuccess() {
            Log.i(TAG, "SdpObserver: onSetSuccess成功");
        }

        @Override
        public void onCreateFailure(String msg) {
            Log.e(TAG, "SdpObserver onCreateFailure失败！！！！！: " + msg);
        }

        @Override
        public void onSetFailure(String msg) {
            Log.e(TAG, "SdpObserver onSetFailure失败！！！！！: " + msg);
        }
    }






    public void doLeave() {
        my_SignalClient.getInstance().initiator = false;
        hangup();


    }
    private void hangup() { //挂断电话
        if (mPeerConnection == null) {
            return;
        }
        mPeerConnection.close();
        mPeerConnection = null;
        updateCallState(true);
    }
    //远程视频是否显示
    private void updateCallState(final boolean idle) {

    }

    //offer
    public void doStartCall() {
        if (mPeerConnection == null) {
            mPeerConnection = createPeerConnection();
        }
        MediaConstraints mediaConstraints = new MediaConstraints();
        mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
        mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
        mediaConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
        mPeerConnection.createOffer(new AudioCallActivity.SimpleSdpObserver() {  //创建offer，这个api和js端的有点不一样
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) { //如果创建成功了，就把这个offer发送到远端
                //Log.i(TAG, "Create local offer success: \n" + sessionDescription.description);
                Log.e(TAG, "设置本地sdp信息成功");
                mPeerConnection.setLocalDescription(new AudioCallActivity.SimpleSdpObserver(), sessionDescription); //设置本地描述，也就是把这个offer保存到本地
                JSONObject message = new JSONObject();
                Log.e(TAG, "创建offer发送给远端");
                JSONObject inner_message = new JSONObject();
                try {
                    message.put("type", "offer");
                    inner_message.put("userId",my_SignalClient.getInstance().userId);
                    inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);
                    inner_message.put("sdp", sessionDescription.description); //把sessionDescription发到信令服务器
                    message.put("message",inner_message);
                    my_SignalClient.getInstance().sendMessage(message);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, mediaConstraints);

    }
    //发送answer
    public void doAnswerCall() {

        if (mPeerConnection == null) {
            mPeerConnection = createPeerConnection();
        }

        MediaConstraints sdpMediaConstraints = new MediaConstraints();
        //试试看下面三行
        sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
        sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
        sdpMediaConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));

        Log.i(TAG, "Create answer ...");
        Log.e(TAG, "给远端发送answer");
        mPeerConnection.createAnswer(new AudioCallActivity.SimpleSdpObserver() {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                Log.i(TAG, "Create answer success !");

                mPeerConnection.setLocalDescription(new AudioCallActivity.SimpleSdpObserver(),
                        sessionDescription); //设置本地answer
                //把answer发送出去
                JSONObject message = new JSONObject();
                JSONObject inner_message = new JSONObject();

                try {
                    message.put("type", "answer");
                    inner_message.put("userId",my_SignalClient.getInstance().userId);
                    inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);
                    inner_message.put("sdp", sessionDescription.description);
                    message.put("message",inner_message);
                    my_SignalClient.getInstance().sendMessage(message);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, sdpMediaConstraints);
        updateCallState(false); //显示远端视频画面
    }

    //**************************************各种约束******************************************/
    private static final String AUDIO_ECHO_CANCELLATION_CONSTRAINT = "googEchoCancellation";
    private static final String AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT = "googAutoGainControl";
    private static final String AUDIO_HIGH_PASS_FILTER_CONSTRAINT = "googHighpassFilter";
    private static final String AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSuppression";
    // 配置音频参数
    private MediaConstraints createAudioConstraints() {
        MediaConstraints audioConstraints = new MediaConstraints();
        audioConstraints.mandatory.add(
                new MediaConstraints.KeyValuePair(AUDIO_ECHO_CANCELLATION_CONSTRAINT, "true"));
        audioConstraints.mandatory.add(
                new MediaConstraints.KeyValuePair(AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT, "false"));
        audioConstraints.mandatory.add(
                new MediaConstraints.KeyValuePair(AUDIO_HIGH_PASS_FILTER_CONSTRAINT, "false"));
        audioConstraints.mandatory.add(
                new MediaConstraints.KeyValuePair(AUDIO_NOISE_SUPPRESSION_CONSTRAINT, "true"));
        return audioConstraints;
    }


    public PeerConnection createPeerConnection() {
        Log.i(TAG, "Create PeerConnection ...");

        LinkedList<PeerConnection.IceServer> iceServers = new LinkedList<PeerConnection.IceServer>();

        //设置stun服务器

        PeerConnection.IceServer ice_server =
                PeerConnection.IceServer.builder("stun:10.19.0.1")
                        .createIceServer();
        iceServers.add(ice_server);


        PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
//        // TCP candidates are only useful when connecting to a server that supports
//        // ICE-TCP.
//        rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED;
//        //rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE;
//        //rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE;
        rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY;
//        // Use ECDSA encryption.
//        //rtcConfig.keyType = PeerConnection.KeyType.ECDSA;
//        // Enable DTLS for normal calls and disable for loopback calls.
        rtcConfig.enableDtlsSrtp = true;
        //rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;
        PeerConnection connection =
                mPeerConnectionFactory.createPeerConnection(rtcConfig,
                        mPeerConnectionObserver);
        if (connection == null) {
            Log.e(TAG, "Failed to createPeerConnection !");
            return null;
        }

        List<String> mediaStreamLabels = Collections.singletonList("ARDAMS");
        mAudioTrack.setVolume(5.0);
        connection.addTrack(mAudioTrack, mediaStreamLabels);

        return connection;
    }

    public PeerConnectionFactory createPeerConnectionFactory(Context context) {

        PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions.builder(context)
                .setEnableInternalTracer(true)
                .createInitializationOptions());

        final VideoEncoderFactory encoderFactory;
        final VideoDecoderFactory decoderFactory;
        //初始化编码与解码工厂

        encoderFactory = new DefaultVideoEncoderFactory(
                mRootEglBase.getEglBaseContext(),
                false ,
                true);


        decoderFactory = new DefaultVideoDecoderFactory(mRootEglBase.getEglBaseContext());



        PeerConnectionFactory.Builder builder = PeerConnectionFactory.builder()
                .setVideoEncoderFactory(encoderFactory)
                .setVideoDecoderFactory(decoderFactory);
        builder.setOptions(null);

        return builder.createPeerConnectionFactory();
    }

    private void changeStateText(){
        //对方接听，开始通话后就把这两个控件设置为gone，并显示远端画面控件
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //stateText.setText("正在通话中...");
            }
        });

    }

    //监听ice服务器返回的事件
    private PeerConnection.Observer mPeerConnectionObserver = new PeerConnection.Observer() {
        @Override
        public void onSignalingChange(PeerConnection.SignalingState signalingState) {
            Log.i(TAG, "onSignalingChange: " + signalingState);
            Log.e(TAG, "Ice信令状态发生变化 " + signalingState);
        }
        //icecandidate是用来表示可用的链路的，一次性应该会有多个icecandidate发过来，是不是因为
//其中的某一个icecandidate不可用了，所以才出现的disconnected,但是我们这里只保留了
        @Override
        public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
            Log.i(TAG, "onIceConnectionChange: " + iceConnectionState);
            Log.e(TAG, "Ice连接状态发生变化：" + iceConnectionState);
            if(iceConnectionState == PeerConnection.IceConnectionState.COMPLETED ||iceConnectionState == PeerConnection.IceConnectionState.CONNECTED) {
                Log.e(TAG, "Ice连接状态发生变化为" + "COMPLETED或CONNECTED"+"表明已发现了可用的icecandidate通路了");
                //changeStateText();
            }
            if(iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED) {
                Log.e(TAG, "Ice连接状态发生变化为" + "DISCONNECTED");
            }
            if(iceConnectionState == PeerConnection.IceConnectionState.FAILED) {
                Log.e(TAG, "这个时候就需要重启ICE了"); //检测到iceConnectionState == 'failed’时，重置peerConnection,创建一个offer发送给对方
            }
        }

        @Override
        public void onIceConnectionReceivingChange(boolean b) {
            Log.i(TAG, "onIceConnectionChange: " + b);
            Log.e(TAG, "ICE连接接收状态改变 " + b);
        }

        @Override
        public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
            Log.i(TAG, "onIceGatheringChange: " + iceGatheringState);
            Log.e(TAG, "ICE收集状态改变。" + iceGatheringState);

        }

        @Override //监听返回的 Candidate ，收集到一个新的ICE候选项时触发
        public void onIceCandidate(IceCandidate iceCandidate) {
            Log.e(TAG, "onIceCandidate: " + iceCandidate);
            Log.e(TAG, "收到ice服务器发回的IceCandidate");
            Log.e(TAG, "把这个IceCandidate发送给远端");

            //延迟发送Candidate，目的是让远端有充足的时间完成setRemoteDescription和setLocalDescription操作，从而保证webrtc顺序图的执行是正确的。
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    /**
                     * 延时执行的代码
                     */
                    try {
                        JSONObject message = new JSONObject();
                        JSONObject inner_message = new JSONObject();
                        JSONObject candidate = new JSONObject();
                        //message.put("userId", RTCSignalClient.getInstance().getUserId());
                        message.put("type", "icecandidate");
                        inner_message.put("userId",my_SignalClient.getInstance().userId);
                        inner_message.put("toUserId",my_SignalClient.getInstance().toUserId);
                        candidate.put("sdpMLineIndex", iceCandidate.sdpMLineIndex);//数字
                        candidate.put("sdpMid", iceCandidate.sdpMid);//字符串
                        candidate.put("sdp", iceCandidate.sdp);//字符串
                        inner_message.put("candidate",candidate);
                        message.put("message",inner_message);
                        my_SignalClient.getInstance().sendMessage(message);
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.e(TAG, "发送ice给远端发生错误");
                    }


                }
            },1000); // 延时1秒



        }
        //当候选项被移除时触发。，这个函数把我们的IceCandidate移除了，很有可能是它引起的disconnected，因为在别人的代码里这个函数为空
        @Override
        public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {
            for (int i = 0; i < iceCandidates.length; i++) {
                Log.i(TAG, "onIceCandidatesRemoved: " + iceCandidates[i]);
                Log.e(TAG, "IceCandidate候选项被移除。" + iceCandidates[i]);
            }
            mPeerConnection.removeIceCandidates(iceCandidates);

        }

        @Override
        public void onAddStream(MediaStream mediaStream) {
            Log.e(TAG, "onAddStream: " + mediaStream.videoTracks.size());
        }

        @Override
        public void onRemoveStream(MediaStream mediaStream) {
            Log.i(TAG, "onRemoveStream");
        }

        @Override
        public void onDataChannel(DataChannel dataChannel) {
            Log.i(TAG, "onDataChannel");
        }

        @Override
        public void onRenegotiationNeeded() {
            Log.i(TAG, "onRenegotiationNeeded");
            //Log.e(TAG, "需要重新协商");
        }

        @Override //接收远端视频流并显示
        public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {

        }
    };
    //信令服务器事件监听
    private my_SignalClient.OnSignalEventListener
            mOnSignalEventListener = new my_SignalClient.OnSignalEventListener() {
        @Override
        public void start_call(){
            if (mPeerConnection == null) {
                mPeerConnection = createPeerConnection();
            }
            doStartCall();

        }

        @Override
        public void onConnected() {

        }

        @Override
        public void onConnecting() {

        }

        @Override
        public void onDisconnected() {

        }

        @Override
        public void onUserJoined(String roomName, String userID) { //连接信令服务器后会收到joined事件，然后这个函数被调用


            mState = "joined";

            //这里应该创建PeerConnection
            if (mPeerConnection == null) {
                mPeerConnection = createPeerConnection();
            }
        }

        @Override
        public void onUserLeaved(String roomName, String userID) {

            mState = "leaved";
        }

        @Override
        public void onRemoteUserJoined(String roomName) {

            if (mState.equals("joined_unbind")) {
                if (mPeerConnection == null) {
                    mPeerConnection = createPeerConnection();
                }
            }

            mState = "joined_conn";
            //调用call， 进行媒体协商
            doStartCall();
        }

        @Override
        public void onRemoteUserLeaved(String roomName, String userID) {
            mState = "joined_unbind";

            if (mPeerConnection != null) {
                mPeerConnection.close();
                mPeerConnection = null;
            }
        }

        @Override
        public void onRoomFull(String roomName, String userID) {
            mState = "leaved";

            PeerConnectionFactory.stopInternalTracingCapture();
            PeerConnectionFactory.shutdownInternalTracer();

            if (mPeerConnectionFactory != null) {
                mPeerConnectionFactory.dispose();
                mPeerConnectionFactory = null;
            }

            finish();
        }

        @Override
        public void onMessage(JSONObject message) {

            Log.i(TAG, "onMessage: " + message);

            try {
                String type = message.getString("type");
                if (type.equals("offer")) {
                    onRemoteOfferReceived(message);
                } else if (type.equals("answer")) {
                    onRemoteAnswerReceived(message);
                } else if (type.equals("icecandidate")) {
                    onRemoteCandidateReceived(message);
                } else if (type.equals("hangup")) {
                    onRemoteHangup();
                } else if(type.equals("refuse")){
                    onRemoteRefuse();
                }
                else {
                    Log.w(TAG, "the type is invalid: " + type);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        private void onRemoteOfferReceived(JSONObject message) {
            Log.e(TAG, "收到远端的offer");
            if (mPeerConnection == null) {
                mPeerConnection = createPeerConnection();
            }

            try {
                String description = message.getJSONObject("message").getString("sdp");
                mPeerConnection.setRemoteDescription(  //设置远端描述
                        new AudioCallActivity.SimpleSdpObserver(),
                        new SessionDescription(
                                SessionDescription.Type.OFFER,
                                description));
                doAnswerCall();  //发送answer
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        private void onRemoteAnswerReceived(JSONObject message) {
            Log.e(TAG, "收到远端的answer");
            try {
                String description = message.getJSONObject("message").getString("sdp");
                mPeerConnection.setRemoteDescription(
                        new AudioCallActivity.SimpleSdpObserver(),
                        new SessionDescription(
                                SessionDescription.Type.ANSWER,
                                description));
            } catch (JSONException e) {
                e.printStackTrace();
            }
            updateCallState(false);
        }

        private void onRemoteCandidateReceived(JSONObject message) {
            Log.e(TAG, "收到远端的icecandidate");
            try {
                JSONObject candidateObj = message.getJSONObject("message").getJSONObject("candidate");
                IceCandidate remoteIceCandidate =
                        new IceCandidate(candidateObj.getString("sdpMid"),
                                candidateObj.getInteger("sdpMLineIndex"),
                                candidateObj.getString("sdp"));
                //难道是icecandidate添加方式出了问题吗？
                Log.e(TAG, "成功添加远端的icecandidate到本地");
                if(mPeerConnection.getRemoteDescription() == null ||mPeerConnection.getLocalDescription() == null){
                    Log.e(TAG, "RemoteDescription或者LocalDescription还是null的时候就开始添加icecandidate了？？？？？");
                }
                boolean flag = mPeerConnection.addIceCandidate(remoteIceCandidate);
                if(flag){
                    Log.e(TAG, "成功添加远端的icecandidate到本地");
                }
                else{
                    Log.e(TAG, "添加远端的icecandidate到本地失败！！！！！！！！！！！！！！！");
                }
            } catch (JSONException e) {
                e.printStackTrace();
                Log.e(TAG, "tianjia远端的icecandidate fashengcuowu");
            }
        }


        private void onRemoteRefuse(){
            Log.e(TAG, "远端拒绝接听");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(),"护士站拒绝接听请求",Toast.LENGTH_LONG).show();
                }
            });

            finish();//关闭活动
        }
        private void onRemoteHangup() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(),"通话结束",Toast.LENGTH_LONG).show();
                }
            });
            my_SignalClient.getInstance().callEndRing();
            finish();
        }
    };


}
